package com.szxy.lambda;

import org.apache.poi.hssf.record.formula.functions.T;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestTemplate;

import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * @Author:zwer
 * @Date:2020/4/15 23:51
 * @Description:com.szxy.lambda
 * @Version:1.0
 *方法引用和构造器引用
 * 1. 对象::实例方法名
 * 2. 类型::静态方法名
 * 3. 类名::实例方法名
 * 4. 类名::new  --> 构造器引用
 * 5. 数据类型 :: new --> 特殊的构造器引用，数据的构造器引用
 *
 **/
public class MethodReferenceTest {

    @Test
    public void test() {
        List<String> list = new ArrayList<>();
        list.add("Hello");
        list.add("Hello123");
        list.add("World");
        list.add("Java");

        // 使用 Lambda 表达式
        list.forEach((str) -> System.out.println(str));

        System.out.println("==========");
        // 对象::实例方法名
        list.forEach(System.out::println);

    }

    @Test
    public void test2() {
        // Lambda 表达式
        // Stream<Double> stream = Stream.generate(() -> Math.random());

        // 类名::静态方法名
        Stream<Double> stream = Stream.generate(Math::random);

        stream.forEach(System.out::println);
    }


    @Test
    public void test3() {
        // 第一种方式
        // Set<String> list = new TreeSet<>(( o1,  o2) -> o1.compareToIgnoreCase(o2));

        // 方法引用   类型::静态方法名
        Set<String> list = new TreeSet<>(String::compareToIgnoreCase);

        list.add("jack");
        list.add("rose");
        list.add("tom");
        list.add("ili");

        list.forEach(System.out::println);
    }

    /**
     * 自定义方法
     */
    public <T> T  method(Supplier<T> s) {
        // 供给型接口
        return  s.get();
    }

    @Test
    public void test4() {
        String hello = method(() -> new String("Hello"));
        System.out.println(hello);

        // 构造器引用
        method(String::new);
    }

    /**
     * 创建一个长度为 2 n次幂的数组
     * @param function
     * @param length
     * @param <R>
     * @return
     */
    public <R> R[] creatArray(Function<Integer, R[]> function, int length) {
        int n = length - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        length = (n < 0) ? 1 : n + 1;
        return function.apply(length);
    }

    @Test
    public void test5() {
        // String[] str = creatArray((length) -> new String[length], 4);

        String[] str = creatArray(String[]::new,9);
        // 数据类型 :: new --> 特殊的构造器引用，数据的构造器引用
        System.out.println("str.length = " + str.length);
    }

}
